// TODO: CODE REVIEW & CLEANUP!
//
// MusicArtistScreen.xaml.cs
//

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Xml;
using HomeUX.ClientAppSupport;
using HomeUX.ClientControlSupport;
using HomeUX.Controls;
using HomeUX.Synchronization;
using HomeUX.Utilities;

namespace HomeUX.MusicClientLibrary
{

public partial class MusicArtistScreen : UserControl
{
    MusicClientHelper _musicClientHelper;

    public string ArtistName { get; set; } // set by a "caller" before navigating here

    /// <summary>
    /// A <n>String.Format</n>-style format string to use for <n>HeaderTextBlock</n>.  Initialized
    /// from the design-time text value of  <n>HeaderTextBlock</n>.
    /// </summary>
    string _headerFormatString;

    public MusicArtistScreen()
    {
        InitializeComponent();
        
        // initialize <_headerFormatString>
        _headerFormatString = HeaderTextBlock.Text;

        Loaded += MusicArtistScreen_Loaded;
        GotFocus += MusicArtistScreen_GotFocus;
    }

    void MusicArtistScreen_Loaded(object sender, RoutedEventArgs e)
    {
        _musicClientHelper = new MusicClientHelper(this, BeginLoadingDataFromMusicServer,
            OnParcelReceived);
        _musicClientHelper.Screen.Opened += OnScreenOpened;

        // reset screen state if we disconnect, or connect to a different server
        _musicClientHelper.Screen.Reset += delegate
        {
            AlbumsListBox.Items.Clear();
            ArtistName = null;
            _musicClientHelper.SetErrorState();
        };
    }

    void OnScreenOpened(object sender, EventArgs e)
    {
        // if the required properties were not set correctly before navigating to this screen,
        // this screen is in an error state
        if (ArtistName == null)
        {
            _musicClientHelper.SetErrorState();
            return;
        }

        HeaderTextBlock.Text = String.Format(_headerFormatString, ArtistName, _musicClientHelper.MusicDeviceName);

		// do the same thing we'd do if we were waiting for the music server to become available
        _musicClientHelper.TryToLoadData();
    }

    void BeginLoadingDataFromMusicServer()
    {
        AlbumsListBox.Items.Clear();
        string command = ParsedSyncNodeCommand.Format("GetAlbumsOfArtist",
            "RecipientId", XmlConvert.ToString(_musicClientHelper.RecipientId),
            "ArtistName", ArtistName);
        _musicClientHelper.MusicDeviceNode.ExecuteCommand(command);
    }

    void OnParcelReceived(Guid recipientId, XmlReader reader)
    {
        try
        {
            string artistName = null, albumId = null, albumName = null;
            byte[] albumArtBytes = null;
            foreach (XmlElementInfo element in XmlElementInfo.EnumerateElements(reader))
            {
                switch (element.Name)
                {

                case "Albums":

                    artistName = element.GetRequiredAttribute("ArtistName");
                    break;
   
                case "Album":

                    albumId = element.GetRequiredAttribute("Id");
                    albumName = element.GetRequiredAttribute("Name");
                    albumArtBytes = null;
                    break;

                case "AlbumArt":

                    albumArtBytes = element.GetContentAsBytes();
                    break;

                case "/Album":

                    AddAlbumToList(albumId, albumName, albumArtBytes);
                    break;

                case "/Albums":

                    if (artistName == ArtistName)
                        _musicClientHelper.OnDataLoaded();
                    else
                        AlbumsListBox.Items.Clear();
                    break;

                }
            }
        }
        catch (InvalidOperationException ex)
        {
            ClientGlobals.Alert(AlertType.Warning,
                "Invalid reply from server: {0}", ex.Message);
        }
    }

    void AddAlbumToList(string albumId, string albumName, byte[] albumArtBytes)
    {
        BitmapImage albumArt;
        if (albumArtBytes != null)
        {
            using (var stream = new MemoryStream(albumArtBytes))
            {
                albumArt = new BitmapImage();
                albumArt.SetSource(stream);
            }
        }
        else
            albumArt = null;

        var buttonFace = new HomeUX.MusicClientLibrary.AlbumButtonFace()
        {
            Tag = albumId,
            AlbumName = albumName
        };

        if (albumArt != null)
        {
            buttonFace.AlbumArt = albumArt;
        }

        AlbumsListBox.Items.Add(buttonFace);
    }

    void MusicArtistScreen_GotFocus(object sender, RoutedEventArgs e)
    {
        AlbumsListBox.Focus();
    }

    private void AlbumsListBox_ItemClick(object sender, ItemClickEventArgs e)
    {
        string albumId = Item.GetUntypedValue(e.Item);

        Screen screen;
        MusicAlbumScreen screenControl;
        _musicClientHelper.FindMusicScreen("Album", out screen, out screenControl);
        screenControl.AlbumId = albumId;
        screenControl.HighlightTrackNumber = -1;
        screen.GoTo();
    }
}

}
